package Week_08

//190. 颠倒二进制位

func ReverseBits() uint32 {
	var num uint32
	num = 222222
	return reverseBits(num)
}

/*
直接颠倒计算每一位的数字
32位 int 标记 [0 ~ 31]，如果 n 的第 i 位为1，则相应的res 第 31 - i 位应该为1
类似地，如果 n 的第 i 位为0，则相应的 res 第 31 - i 位应该为0
res初始化为0，每次考虑 n的某一位，移动到颠倒后的位置，设该位表示的数为temp，temp只有两种情况，要么等于0，要么等于一个2的幂次(相当于二进制000... 1 ...0000这种形式)
对于temp = 0，res加上0相当于没加，和0按位或、异或还是等于原来的数，所以这三者是一样的
对于temp = 2^(31 - i)，temp二进制下只有一位为1，看样子似乎+=和|=不一样，但是不要忘了我们是按位循环的，当进行到31 - i这一位时，res的这一位还是0，那么就回到上一种情况了，+=,|=, ^=这三种种写法其实还是等效的。
因为考虑的temp只有某一位，每次对应于res也是是其中某一位，而且由于是按位考虑，所以每次遍历到该位时，res二进制下的这一位也还是0，res |= ... , res += ... , res |= ...都是等价的，都是在表达，只要temp的该位为1，res该位就为1，因为res的那一位一开始是0，如果temp该位为0，由于res这一位也为0,那么0 + 0, 0 | 0, 0 ^ 0其实都等于0。三种写法都可以，但是更推荐使用位运算

*/
func reverseBits(num uint32) uint32 {
	var res uint32 = 0
	for i := 0; i < 32; i++ {
		if (num & (1 << i)) != 0 {
			res ^= 1 << (31 - i)
		} else {
			res ^= 0
		}
	}
	return res
}
